package ginv

import (
	"context"
	"fmt"
	"net/http"
	"gorm.io/gorm"
	"github.com/go-redis/redis/v8"
)

// 完整的项目示例 - 展示如何在实际项目中使用Gin链式处理器 + BindCombo

// ===== 全局配置定义 =====

// 数据库连接配置
var DatabaseConfig = struct {
	MainDB    *gorm.DB `confx:"name=MainDB"`
	PaymentDB *gorm.DB `confx:"name=PaymentDB"`
}{}

// Redis连接配置
var RedisConfig = struct {
	MainRedis  *redis.Client `confx:"name=MainRedis"`
	CacheRedis *redis.Client `confx:"name=CacheRedis"`
}{}

// 应用配置
type ServiceConfig struct {
	AppID     string `json:"app_id"`
	AppSecret string `json:"app_secret"`
	BaseURL   string `json:"base_url"`
	Timeout   int    `json:"timeout"`
}

var AppConfig = struct {
	PaymentService *ServiceConfig `confx:"format=json"`
	UserService    *ServiceConfig `confx:"format=json"`
}{}

// ===== 业务模型 =====

type PartTimeJob struct {
	ID          int64  `json:"id" gorm:"primaryKey"`
	Title       string `json:"title"`
	Description string `json:"description"`
	Salary      int64  `json:"salary"`
	Status      string `json:"status"`
	CreatedAt   int64  `json:"created_at"`
}

type User struct {
	ID       int64  `json:"id" gorm:"primaryKey"`
	Name     string `json:"name"`
	Email    string `json:"email"`
	Password string `json:"-"`
	Role     string `json:"role"`
}

// ===== 请求响应结构体 =====

// 兼职列表请求
type GetPartTimeListReq struct {
	Page     int32  `json:"page" form:"page" confx:"default=1"`
	PageSize int32  `json:"page_size" form:"page_size" confx:"default=10"`
	Status   string `json:"status" form:"status" confx:"default=active"`
	Keyword  string `json:"keyword" form:"keyword"`
}

// 兼职列表响应
type GetPartTimeListRsp struct {
	Ret  int    `json:"ret"`
	Msg  string `json:"msg"`
	Data struct {
		List  []PartTimeJob `json:"list"`
		Total int64         `json:"total"`
		Page  int32         `json:"page"`
		Size  int32         `json:"size"`
	} `json:"data"`
}

// 创建兼职请求
type CreatePartTimeReq struct {
	Title       string `json:"title" binding:"required"`
	Description string `json:"description" binding:"required"`
	Salary      int64  `json:"salary" binding:"required,min=1"`
}

// 创建兼职响应
type CreatePartTimeRsp struct {
	Ret  int    `json:"ret"`
	Msg  string `json:"msg"`
	Data struct {
		ID int64 `json:"id"`
	} `json:"data"`
}

// 用户注册请求
type RegisterUserReq struct {
	Name     string `json:"name" binding:"required"`
	Email    string `json:"email" binding:"required,email"`
	Password string `json:"password" binding:"required,min=6"`
}

// 用户注册响应
type RegisterUserRsp struct {
	Ret  int    `json:"ret"`
	Msg  string `json:"msg"`
	Data struct {
		UserID int64  `json:"user_id"`
		Token  string `json:"token"`
	} `json:"data"`
}

// ===== 业务处理函数 =====

// 获取兼职列表
func GetPartTimeList(ctx context.Context, req *GetPartTimeListReq, rsp *GetPartTimeListRsp) error {
	// 使用全局数据库连接
	db := DatabaseConfig.MainDB
	if db == nil {
		rsp.Ret = 1
		rsp.Msg = "数据库连接未初始化"
		return nil
	}

	// 使用Redis缓存
	cache := RedisConfig.CacheRedis
	cacheKey := fmt.Sprintf("part_time_list:%d:%d:%s", req.Page, req.PageSize, req.Status)
	
	// 尝试从缓存获取
	if cache != nil {
		cached := cache.Get(ctx, cacheKey)
		if cached.Err() == nil {
			// 缓存命中逻辑...
		}
	}

	// 构建查询
	query := db.WithContext(ctx).Model(&PartTimeJob{})
	
	if req.Status != "" {
		query = query.Where("status = ?", req.Status)
	}
	
	if req.Keyword != "" {
		query = query.Where("title LIKE ? OR description LIKE ?", 
			"%"+req.Keyword+"%", "%"+req.Keyword+"%")
	}

	// 获取总数
	var total int64
	if err := query.Count(&total).Error; err != nil {
		rsp.Ret = 1
		rsp.Msg = "查询失败: " + err.Error()
		return nil
	}

	// 分页查询
	var jobs []PartTimeJob
	offset := (req.Page - 1) * req.PageSize
	if err := query.Offset(int(offset)).Limit(int(req.PageSize)).Find(&jobs).Error; err != nil {
		rsp.Ret = 1
		rsp.Msg = "查询失败: " + err.Error()
		return nil
	}

	// 设置缓存
	if cache != nil {
		// 缓存结果...
	}

	// 返回结果
	rsp.Data.List = jobs
	rsp.Data.Total = total
	rsp.Data.Page = req.Page
	rsp.Data.Size = req.PageSize
	rsp.Ret = 0
	rsp.Msg = "查询成功"

	return nil
}

// 创建兼职
func CreatePartTime(ctx context.Context, req *CreatePartTimeReq, rsp *CreatePartTimeRsp) error {
	db := DatabaseConfig.MainDB
	if db == nil {
		rsp.Ret = 1
		rsp.Msg = "数据库连接未初始化"
		return nil
	}

	// 创建兼职记录
	job := &PartTimeJob{
		Title:       req.Title,
		Description: req.Description,
		Salary:      req.Salary,
		Status:      "active",
		CreatedAt:   1640995200, // 实际项目中使用 time.Now().Unix()
	}

	if err := db.WithContext(ctx).Create(job).Error; err != nil {
		rsp.Ret = 1
		rsp.Msg = "创建失败: " + err.Error()
		return nil
	}

	// 清除相关缓存
	cache := RedisConfig.CacheRedis
	if cache != nil {
		// 清除列表缓存...
	}

	rsp.Data.ID = job.ID
	rsp.Ret = 0
	rsp.Msg = "创建成功"

	return nil
}

// 用户注册
func RegisterUser(ctx context.Context, req *RegisterUserReq, rsp *RegisterUserRsp) error {
	db := DatabaseConfig.MainDB
	if db == nil {
		rsp.Ret = 1
		rsp.Msg = "数据库连接未初始化"
		return nil
	}

	// 检查邮箱是否已存在
	var existingUser User
	if err := db.WithContext(ctx).Where("email = ?", req.Email).First(&existingUser).Error; err == nil {
		rsp.Ret = 1
		rsp.Msg = "邮箱已被注册"
		return nil
	}

	// 创建用户（实际项目中需要密码加密）
	user := &User{
		Name:     req.Name,
		Email:    req.Email,
		Password: req.Password, // 实际项目中需要加密
		Role:     "user",
	}

	if err := db.WithContext(ctx).Create(user).Error; err != nil {
		rsp.Ret = 1
		rsp.Msg = "注册失败: " + err.Error()
		return nil
	}

	// 生成token（实际项目中使用JWT）
	token := fmt.Sprintf("token_%d", user.ID)

	// 缓存用户信息
	cache := RedisConfig.MainRedis
	if cache != nil {
		// 缓存用户session...
	}

	rsp.Data.UserID = user.ID
	rsp.Data.Token = token
	rsp.Ret = 0
	rsp.Msg = "注册成功"

	return nil
}

// 健康检查
func HealthCheck(ctx context.Context, req *struct{}, rsp *struct {
	Ret  int    `json:"ret"`
	Msg  string `json:"msg"`
	Data struct {
		Status   string `json:"status"`
		Database string `json:"database"`
		Redis    string `json:"redis"`
	} `json:"data"`
}) error {
	// 检查数据库连接
	dbStatus := "ok"
	if DatabaseConfig.MainDB != nil {
		if sqlDB, err := DatabaseConfig.MainDB.DB(); err != nil || sqlDB.Ping() != nil {
			dbStatus = "error"
		}
	} else {
		dbStatus = "not_configured"
	}

	// 检查Redis连接
	redisStatus := "ok"
	if RedisConfig.MainRedis != nil {
		if err := RedisConfig.MainRedis.Ping(ctx).Err(); err != nil {
			redisStatus = "error"
		}
	} else {
		redisStatus = "not_configured"
	}

	rsp.Data.Status = "ok"
	rsp.Data.Database = dbStatus
	rsp.Data.Redis = redisStatus
	rsp.Ret = 0
	rsp.Msg = "服务正常"

	return nil
}

// ===== 主程序入口 =====

func RunCompleteExample() {
	// 创建完整的链式处理器应用
	app := NewChainHandler().
		// 1. 配置依赖注入
		WithBindCombo(&DatabaseConfig, &RedisConfig, &AppConfig).
		WithConfigFile("config.yaml").
		BuildConfig().
		
		// 2. 配置中间件
		DefaultMiddlewares().
		Use(RequestIDMiddleware()).
		
		// 3. 注册路由
		GET("/health", HealthCheck).
		
		// 兼职相关路由
		POST("/api/part-time/list", GetPartTimeList).
		GET("/api/part-time/list", GetPartTimeList).
		POST("/api/part-time", CreatePartTime).
		
		// 用户相关路由
		POST("/api/user/register", RegisterUser)

	// 4. 创建API版本组
	v1 := app.Group("/api/v1")
	{
		// 兼职管理
		partTime := v1.Group("/part-time")
		{
			partTime.GET("/list", GetPartTimeList)
			partTime.POST("", CreatePartTime)
		}
		
		// 用户管理
		user := v1.Group("/user")
		{
			user.POST("/register", RegisterUser)
		}
	}

	// 5. 启动服务器
	fmt.Println("🚀 服务器启动中...")
	fmt.Println("📊 健康检查: http://localhost:8080/health")
	fmt.Println("📝 API文档: http://localhost:8080/api/v1/")
	
	if err := app.Run(":8080"); err != nil {
		panic("服务器启动失败: " + err.Error())
	}
}